{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9aa6a741",
   "metadata": {},
   "source": [
    "* 学习人：黄嘉欣\n",
    "* 时间：2021-11-15\n",
    "* week12\n",
    "* 学习线上资源：[python官方文档](https://python.org/doc)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b1c529f",
   "metadata": {},
   "source": [
    "# 本周学习目标\n",
    "> 1. 函数的定义\n",
    "\n",
    "> 2. 函数的使用\n",
    "\n",
    "> 3. 函数的参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "715b9fee",
   "metadata": {},
   "source": [
    "## 函数的定义\n",
    ">> 定义一个函数的一般步骤"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "97a05573",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 \n"
     ]
    }
   ],
   "source": [
    "a, b = 0, 1\n",
    "while a < 10:\n",
    "    print(a, end=' ') #a=0\n",
    "    a, b = b, a+b\n",
    "print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "317f2ca3",
   "metadata": {},
   "source": [
    "> 1. 定义函数的一般方法：\n",
    "...\n",
    "def function_name():  # 1.function_name 遵循变量定义的规则 区别于数学函数==> f(x) python的函数可以自定义名称\n",
    "  \"\"\"函数的注释\"\"\"  #  2. 函数的注释可以和使用者交流\n",
    "  函数体         # 3. 函数体要和定义函数保持一定的tab缩进\n",
    "...\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab19d18c",
   "metadata": {},
   "outputs": [],
   "source": [
    "#......想重复使用某一个功能（避免重复造轮子）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "3d2460ad",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fib(n):    # write Fibonacci series up to n\n",
    "...     \"\"\"Print a Fibonacci series up to n.\"\"\"\n",
    "...     a, b = 0, 1\n",
    "...     while a < n:\n",
    "...         print(a, end=' ')\n",
    "...         a, b = b, a+b\n",
    "...     print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a68bdac3",
   "metadata": {},
   "source": [
    "### 2. 函数的使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "e9a62b2c",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 \n"
     ]
    }
   ],
   "source": [
    "fib(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "0c0639ae",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 \n"
     ]
    }
   ],
   "source": [
    "fib(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "601c7242",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "# 写一个函数 实现hello world\n",
    "#  写一个函数 实现 hello username\n",
    "def hw():\n",
    "    \"\"\"实现hello world\"\"\"\n",
    "    print(\"hello world\")\n",
    "hw()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f23b5cc1",
   "metadata": {},
   "outputs": [],
   "source": [
    "#（1）在第一行定义函数中，不需要任何信息就能完成工作，因此括号是空的（即便如此，括号必不可少！）\n",
    "\n",
    "　#　　（2）要调用函数，可以依次指定函数名以及括号括起的必要信息。在第五行代码中，因为此函数greet_uesr()括号中不需要任何信息，只需要输入greet_uesr（）即可。和预期效果一样，打印Hello！："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "1e6984c8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello~嘉欣美女\n"
     ]
    }
   ],
   "source": [
    "def user_name(username):\n",
    "    \"\"\"实现你好，嘉欣\"\"\"\n",
    "    print(\"hello~\"+ username.title()+\"美女\")\n",
    "user_name(\"嘉欣\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "46a3b94c",
   "metadata": {},
   "source": [
    "* 函数是否必须有参数？\n",
    "> 1. 在第一行定义函数中，不需要任何信息就能完成工作，因此括号是空的（即便如此，括号必不可少！）\n",
    "> 2. 要调用函数，可以依次指定函数名以及括号括起的必要信息。在第五行代码中，因为此函数greet_uesr()括号中不需要任何信息，只需要输入greet_uesr（）即可。和预期效果一样，打印Hello！：\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96e75e97",
   "metadata": {},
   "source": [
    "### 3.函数的参数\n",
    "> 1. 形式参数：定义函数时，写在function_name括号里面的参数\n",
    ">> 1. 在定义函数时，形式参数不占用空间\n",
    "> 2. 实际参数：调用函数时，写在function_name括号里面的参数\n",
    ">> 2. 在使用函数时，形式参数被分配空间，变为实际参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "bf58eaaa",
   "metadata": {},
   "outputs": [],
   "source": [
    "def describe_pet(animal_type,pet_name):   #animal_type，pet_name是形式参数\n",
    "     \"\"\"显示宠物信息\"\"\"\n",
    "     print(\"\\nI have a\" + animal_type + \".\")\n",
    "     print(\"My\" +  animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "918dabac",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is Didi.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"dog\",\"didi\") # \"dog\",\"didi\"实际参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "ce66e50f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adidi.\n",
      "Mydidi's name is Dog.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"didi\",\"dog\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b03685e7",
   "metadata": {},
   "source": [
    "* 当函数具有多个参数时\n",
    "\n",
    "> 1. 位置参数\n",
    ">> 1. 形式参数有先后顺序，函数调用过程中因考虑参数的先后顺序，避免出现顺序错误的笑话\n",
    ">> 2. 调用函数过程中，要考虑形式参数的个数。\n",
    "> 2. 关键字参数\n",
    ">> 1. 调用函数时，通过赋值的方式传递给定义好的形参变量数据。\n",
    ">> 2. 关键字参数不考虑先后顺序，因为时指定变量赋值。\n",
    "> 3. 默认参数\n",
    ">> 1. 在形式参数中，提前预先设置一个用户可能使用的参数值\n",
    ">> 2. 用户在调用函数时，可以省略不给默认参数赋值\n",
    ">> 3. 用户给默认参数赋值，将替换默认参数的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6fa52066",
   "metadata": {},
   "outputs": [],
   "source": [
    "def describe_pet(animal_type,pet_name):   #animal_type，pet_name是形式参数\n",
    "     \"\"\"显示宠物信息\"\"\"\n",
    "     print(\"\\nI have a\" + animal_type + \".\")\n",
    "     print(\"My\" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e43da2c3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 在使用 describe_pet() 函数时 需要考虑参数的位置，从而进行参数数据的输入（实参的调用）\n",
    "describe_pet(\"dog\",\"didi\")  # 要根据形式参数的位置的先后顺序，先写animal_type，再写pet_name\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "74e6a5d0",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "describe_pet() missing 1 required positional argument: 'pet_name'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-29-a70f5cbb422b>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mdescribe_pet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"dog\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: describe_pet() missing 1 required positional argument: 'pet_name'"
     ]
    }
   ],
   "source": [
    "describe_pet(\"dog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "05ecf081",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is Didi.\n"
     ]
    }
   ],
   "source": [
    "# 关键字参数使用 两个参数可以调换先后顺序也不影响\n",
    "describe_pet(animal_type=\"dog\",pet_name=\"didi\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "7219dbb3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function describe_pet in module __main__:\n",
      "\n",
      "describe_pet(animal_type, pet_name)\n",
      "    显示宠物信息\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(describe_pet)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a00081f",
   "metadata": {},
   "source": [
    "-------\n",
    "参数使用过程中的思考与问题：\n",
    "> 1. 思考：关键字参数和位置参数是否可以一起使用？\n",
    ">> 1. positional argument follows keyword argument(位置参数<font style=\"color:red\">均</font>要放在关键字参数的前面)\n",
    ">> 2. got multiple values for argument 'x'(映射，不能出现重复的多重的值)\n",
    "> 2.定义函数：默认参数和非默认参数的先后关系\n",
    ">> 1.non-default argument follows default argument(非默认参数均要放在默认参数前面)\n",
    "-------\n",
    "* 以下为测试代码：\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "cc4d41c9",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test1(x,y,z):\n",
    "    \"\"\"打印下x，y，z\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "a0e0e64d",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-36-9fe5e54f9158>, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-36-9fe5e54f9158>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m    text1(x=2,1,z=4)\u001b[0m\n\u001b[1;37m              ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "test1(x=2,1,z=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "cef8d8b7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "test1(2,y=3,z=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "f7278330",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "test1(2,z=2,y=1) # 关键字参数位置可以调换哦！"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "be5361fb",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "test1() got multiple values for argument 'x'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-40-90a320ba5220>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mtest1\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: test1() got multiple values for argument 'x'"
     ]
    }
   ],
   "source": [
    "test1(2,x=1,y=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "a793811b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 案例2\n",
    "def test1(x,z,y=3):\n",
    "    \"\"\"打印x,y,z的值\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "adc50751",
   "metadata": {},
   "source": [
    "## 4.课本练习实践\n",
    "> 1. 总结函数的优势\n",
    "> 2. 预习课本第四章函数与模块\n",
    ">> 1. 完成课本元音字母的实践\n",
    ">> 2. 浏览模块，创建模块和调用模块，了解PEP 8 python国际代码标准"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "78f7de2a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def search4vowels(word):\n",
    "    \"\"\"判断输入文本出现的元音字母有哪些\"\"\"\n",
    "    vowels = set(\"aeiou\")\n",
    "    word = set(word)\n",
    "    print(vowels & word)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "f4ea46c3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'u', 'e', 'a'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"default\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6cad4ad0",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
